#ifndef NODE_H
#define NODE_H

#include <iostream>

using std::cerr;
using std::cout;
using std::endl;

// Do not add any #include statements here.  If you have a convincing need for adding a different `#include` please email me
// your code for the Node class goes here:
// (Note the 'NodeIterator' class will report lots of errors until Node exists)

template <typename T>
struct Node
{
    T data;
    Node<T> *previous;
    Node<T> *next;

    Node(T dataIn)
        : data(dataIn), previous(nullptr), next(nullptr)
    {
    }
};

template <typename T>
class NodeIterator
{
private:
    Node<T> *current;

public:
    NodeIterator(Node<T> *currentIn)
        : current(currentIn)
    {
    }

    T &operator*()
    {
        return current->data;
    }

    // complete the code for NodeIterator here
    NodeIterator &operator++()
    {
        if (current == nullptr)
        {
            return *this;
        }
        current = current->next;
        return *this;
    }

    NodeIterator &operator--()
    {
        if (current == nullptr)
        {
            return *this;
        }
        current = current->previous;
        return *this;
    }

    bool operator==(const NodeIterator &other) const
    {
        return current == other.current;
    }

    bool operator!=(const NodeIterator &other) const
    {
        return current != other.current;
    }

    Node<T> *operator->()
    {
        return current;
    }
};

// do not edit below this line

#endif
